/*
 * main.c
 *
 *  Created on: 29/gen/2014
 *      Author: Postazione Embedded
 */
//TX mario, RX diana
//canale 7a


#include "stm32f4xx.h"
#include "leds/leds.h"
#include "spi/spi_conf.h"
#include "interruption/interruption.h"
#include "nrf24l01p/nRF24L01P.h"

//#define SPI_GPIO GPIOA
#define SPI_SCK_PIN GPIO_PinSource5
#define SPI_MISO_PIN GPIO_PinSource6
#define SPI_MOSI_PIN GPIO_PinSource7

nRF24L01_Device rf;
spi_Device spi;

unsigned char RX_ADDRESS[ADR_WIDTH] = { 'm', 'a', 'r', 'i', 'o' };
unsigned char TX_ADDRESS[ADR_WIDTH] = { 'd', 'i', 'a', 'n', 'a' };



static uint32_t counter = 0;
//static uint32_t del = 3500 * 500 * 2;

uint8_t tx_mutex = 1;

void EXTI9_5_IRQHandler(void) {
	if (EXTI_GetITStatus(rf.IRQ_EXTI_Line) != RESET) {
		EXTI_ClearITPendingBit(rf.IRQ_EXTI_Line);
		uint8_t status;
		//do {
			status = nRF24L01_get_status(&rf);
			if ((status & 0x40) != 0) {
				//RX_INTERRUPT
				nRF24L01_CE_L(&rf);
				uint8_t fifo_status;
				status = nRF24L01_get_fifo_status(&rf, &fifo_status);
				uint8_t buff[32];
				uint8_t length;

				nRF24L01_get_payload_length(&rf, &length);

				if (length > 32 || length == 0) {
					nRF24L01_flush_rx(&rf);
				} else {
					SPI_Read_Buf(&rf, RD_RX_PLOAD, &buff, length);
					status = nRF24L01_set_status(&rf, 0x40);
					toggleLeds(LED[buff[0]]);
				}
				nRF24L01_CE_H(&rf);
			}
			if ((status & 0x20) != 0) {
				//TX_INTERRUPT
				nRF24L01_CE_L(&rf);
				toggleLeds(LED[0]);
				status = nRF24L01_set_status(&rf, 0x20);
				tx_mutex = 1;
				//nRF24L01_CE_H(&rf);
			}
			if ((status & 0x10) != 0) {
				//MAX_RT_INTERRUPT
				nRF24L01_CE_L(&rf);
				status = nRF24L01_set_status(&rf, 0x10);
				nRF24L01_flush_tx(&rf);
				toggleLeds(LED[2]);
				tx_mutex = 1;
			}
		//}while((status & (0x70)) != 0);
	}
}

void setupt() {
	gpioLedsConfiguration();

	spi.SPIx = SPI1;
	spi.SPI_GPIO = GPIOA;
	spi.SCK_Pin_Source = SPI_SCK_PIN;
	spi.MISO_Pin_Source = SPI_MISO_PIN;
	spi.MOSI_Pin_Source = SPI_MOSI_PIN;

	rf.spi_Device = &spi;
	rf.CE_GPIO = GPIOA;
	rf.CE_Pin = GPIO_Pin_3;
	rf.CSN_GPIO = GPIOA;
	rf.CSN_Pin = GPIO_Pin_4;
	rf.IRQ_GPIO = GPIOE;
	rf.IRQ_Pin = GPIO_Pin_9;
	rf.IRQ_GPIO_PortSource = EXTI_PortSourceGPIOE;
	rf.IRQ_GPIO_PinSource = EXTI_PinSource9;
	rf.IRQ_EXTI_Line = EXTI_Line9;

	init_nRF24L01(&rf);
	uint8_t status;
	nRF24L01_set_config(&rf, CONFIG_RX_DR_ENABLE_INTERRUPT | CONFIG_TX_DS_ENABLE_INTERRUPT | CONFIG_MAX_RT_ENABLE_INTERRUPT | CONFIG_ENABLE_CRC | CONFIG_CRC_2_Byte | CONFIG_PWR_UP | CONFIG_PTX);
	nRF24L01_Delay_us(15000);
	nRF24L01_set_auto_ack(&rf, EN_AA_P0 | EN_AA_P1);
	nRF24L01_set_enable_pipe(&rf, ENRX_P0 | ENRX_P1);
	nRF24L01_set_address_width(&rf, AW_5_BYTES);
	nRF24L01_set_retransmission(&rf, ARD_4000_US | ARC_15);
	nRF24L01_set_channel(&rf, 0x7a);
	nRF24L01_set_status(&rf, RX_DR | TX_DS | MAX_RT);
	nRF24L01_setTXAddress(&rf, TX_ADDRESS);
	nRF24L01_setRXAddress(&rf, PIPE_0, TX_ADDRESS);
	nRF24L01_setRXAddress(&rf, PIPE_1, RX_ADDRESS);


	status = SPI_WR_Reg(&rf, 0x1D, 0x04);
	status = SPI_WR_Reg(&rf, 0x1C, 0x3f);

	nRF24L01_flush_rx(&rf);
	nRF24L01_flush_tx(&rf);

	//nRF24L01_CE_H(&rf);


}

void setupr() {
	gpioLedsConfiguration();

	spi.SPIx = SPI1;
	spi.SPI_GPIO = GPIOA;
	spi.SCK_Pin_Source = SPI_SCK_PIN;
	spi.MISO_Pin_Source = SPI_MISO_PIN;
	spi.MOSI_Pin_Source = SPI_MOSI_PIN;

	rf.spi_Device = &spi;
	rf.CE_GPIO = GPIOA;
	rf.CE_Pin = GPIO_Pin_3;
	rf.CSN_GPIO = GPIOA;
	rf.CSN_Pin = GPIO_Pin_4;
	rf.IRQ_GPIO = GPIOE;
	rf.IRQ_Pin = GPIO_Pin_9;
	rf.IRQ_GPIO_PortSource = EXTI_PortSourceGPIOE;
	rf.IRQ_GPIO_PinSource = EXTI_PinSource9;
	rf.IRQ_EXTI_Line = EXTI_Line9;

	init_nRF24L01(&rf);
	uint8_t status;
	status = SPI_WR_Reg(&rf, CONFIG, 0x0f);
	nRF24L01_Delay_us(15000);
	status = SPI_WR_Reg(&rf, EN_AA, 0x3f);
	status = SPI_WR_Reg(&rf, EN_RXADDR, 0x3f);
	status = SPI_WR_Reg(&rf, SETUP_AW, AW_5_BYTES);
	status = SPI_WR_Reg(&rf, SETUP_RETR, 0xff);
	status = SPI_WR_Reg(&rf, RF_CH, 0x7a);
	status = SPI_WR_Reg(&rf, NRFRegSTATUS, 0x70);
	status = SPI_WR_Reg(&rf, RX_PW_P0, 1);
	status = SPI_WR_Reg(&rf, RX_PW_P1, 1);
	status = SPI_Write_Buf(&rf, RX_ADDR_P0, RX_ADDRESS, ADR_WIDTH);
	status = SPI_Write_Buf(&rf, RX_ADDR_P1, TX_ADDRESS, ADR_WIDTH);
	status = SPI_Write_Buf(&rf, TX_ADDR, RX_ADDRESS, ADR_WIDTH);
	status = SPI_WR_Reg(&rf, 0x1D, 0x04);
	status = SPI_WR_Reg(&rf, 0x1C, 0x3f);

	nRF24L01_flush_rx(&rf);
	nRF24L01_flush_tx(&rf);

	nRF24L01_CE_H(&rf);

}

int doLoop() {
	return 1;
}

void loopr() {

}

void loopt() {
	if(tx_mutex == 1){
		tx_mutex=0;
		counter++;
		uint8_t data = counter%4;
		SPI_Write_Buf(&rf, WR_TX_PLOAD, &data, 32);
		nRF24L01_CE_H(&rf);
	}
}

void finalize() {

}

int main() {
	setupr();
	while (doLoop()) {
		loopr();
	}

	finalize();
}

